//
//  InvestmentBasicParameter.m
//  DataCollector
//
//  Created by jiro on 12/07/02.
//  Copyright 2012 jiro music. All rights reserved.
//

#import "FxInvestmentBasicParameterSet.h"

#import "../Commons.h"
#import "StrategyParameters.h"

FxInvestmentBasicParameterSet::FxInvestmentBasicParameterSet( const FxInvestmentBasicParameterSet& p )
	: StrategyParameterSet( static_cast< const StrategyParameterSet& >( p ) )
{}

FxInvestmentBasicParameterSet::FxInvestmentBasicParameterSet( const std::vector< const char* >& values )
	: StrategyParameterSet( values )
{
	const int baseClassParamCount = StrategyParameterSet::parameterCount();

	NSString* currencyCode = [ NSString stringWithCString: values[ baseClassParamCount + Id_CurrencyCode ] encoding: NSUTF8StringEncoding ];
	NSString* targetCurrencyCode = [ NSString stringWithCString: values[ baseClassParamCount + Id_TargetCurrencyCode ] encoding: NSUTF8StringEncoding ];
	double investMoney = atof( values[ baseClassParamCount + Id_InvestMoney ] );
	double targetInterest = atof( values[ baseClassParamCount + Id_TargetInterestArg ] );
	double tolerenctLossRate = atof( values[ baseClassParamCount + Id_TolerenctLossRateArg ] );
	double leverage = atof( values[ baseClassParamCount + Id_LeverageArg ] );
	double entryExchange = atof( values[ baseClassParamCount + Id_EntryExchangeArg ] );
	double targetSettlementExchangeRateGap = atof( values[ baseClassParamCount + Id_TargetSettlementExchangeRateGapArg ] );
	double lossCutExchangeRateGap = atof( values[ baseClassParamCount + Id_LossCutExchangeRateGapArg ] );
	double spread = atof( values[ baseClassParamCount + Id_SpreadArg ] );
	double charge = atof( values[ baseClassParamCount + Id_ChargeArg ] );
	int tradeCount = atoi( values[ baseClassParamCount + Id_TradeCountArg ] );
	InvestmentPosition::Type investmentPositionType = static_cast< InvestmentPosition::Type >( atoi( values[ baseClassParamCount + Id_InvestmentPositionTypeArg ] ) );
	
	strategyParameters.push_back( new StrategyStringParameter( currencyCode ) );
	strategyParameters.push_back( new StrategyStringParameter( targetCurrencyCode ) );
	strategyParameters.push_back( new StrategyDoubleParameter( investMoney ) );
	strategyParameters.push_back( new StrategyDoubleParameter( targetInterest ) );
	strategyParameters.push_back( new StrategyDoubleParameter( tolerenctLossRate ) );
	strategyParameters.push_back( new StrategyDoubleParameter( leverage ) );
	strategyParameters.push_back( new StrategyDoubleParameter( entryExchange ) );
	strategyParameters.push_back( new StrategyDoubleParameter( targetSettlementExchangeRateGap ) );
	strategyParameters.push_back( new StrategyDoubleParameter( lossCutExchangeRateGap ) );
	strategyParameters.push_back( new StrategyDoubleParameter( spread ) );
	strategyParameters.push_back( new StrategyDoubleParameter( charge ) );
	strategyParameters.push_back( new StrategyDoubleParameter( tradeCount ) );
	strategyParameters.push_back( new StrategyDoubleParameter( investmentPositionType ) );
}

FxInvestmentBasicParameterSet::FxInvestmentBasicParameterSet(
	NSString* currencyCode,
	NSString* targetCurrencyCode,
	double investMoneyArg,
	double targetInterestArg,
	double tolerenctLossRateArg,
	double leverageArg,
	double entryExchangeArg,
	double targetSettlementExchangeRateGapArg,
	double lossCutExchangeRateGapArg,
	double spreadArg,
	double chargeArg,
	int tradeCountArg,
	InvestmentPosition::Type investmentPositionTypeArg )
{
	strategyParameters.push_back( new StrategyStringParameter( currencyCode ) );
	strategyParameters.push_back( new StrategyStringParameter( targetCurrencyCode ) );
	strategyParameters.push_back( new StrategyDoubleParameter( investMoneyArg ) );
	strategyParameters.push_back( new StrategyDoubleParameter( targetInterestArg ) );
	strategyParameters.push_back( new StrategyDoubleParameter( tolerenctLossRateArg ) );
	strategyParameters.push_back( new StrategyDoubleParameter( leverageArg, leverageArg, 0 ) );
	strategyParameters.push_back( new StrategyDoubleParameter( entryExchangeArg, entryExchangeArg, 0 ) );
	strategyParameters.push_back( new StrategyDoubleParameter( targetSettlementExchangeRateGapArg, targetSettlementExchangeRateGapArg, 0 ) );
	strategyParameters.push_back( new StrategyDoubleParameter( lossCutExchangeRateGapArg, lossCutExchangeRateGapArg, 0 ) );
	strategyParameters.push_back( new StrategyDoubleParameter( spreadArg, spreadArg, 0 ) );
	strategyParameters.push_back( new StrategyDoubleParameter( chargeArg, chargeArg, 0 ) );
	strategyParameters.push_back( new StrategyDoubleParameter( tradeCountArg, tradeCountArg, 0 ) );
	strategyParameters.push_back( new StrategyDoubleParameter( investmentPositionTypeArg, investmentPositionTypeArg, 0 ) );
}

FxInvestmentBasicParameterSet::~FxInvestmentBasicParameterSet()
{}

NSString* FxInvestmentBasicParameterSet::queryInsert() const
{
	return NULL;
}
	
NSString* FxInvestmentBasicParameterSet::queryInsertValue() const
{
	return NULL;
}

NSString* FxInvestmentBasicParameterSet::queryInsertWithSerialValue() const
{
	return NULL;
}

NSString* FxInvestmentBasicParameterSet::queryInsertValueWithSerialValue() const
{
	return NULL;
}

int FxInvestmentBasicParameterSet::parameterCount()
{
	return Id_Count;
}

NSString* FxInvestmentBasicParameterSet::getCurrencyCode() const
{
	return strategyParameters[ Id_CurrencyCode ]->getStringValue(); 
}

NSString* FxInvestmentBasicParameterSet::getTargetCurrencyCode() const
{
	return strategyParameters[ Id_TargetCurrencyCode ]->getStringValue(); 
}

double FxInvestmentBasicParameterSet::getInvestMoney() const
{
	return strategyParameters[ Id_InvestMoney ]->getDoubleValue(); 
}

double FxInvestmentBasicParameterSet::getTargetInterest() const
{
	return strategyParameters[ Id_TargetInterestArg ]->getDoubleValue(); 
}

double FxInvestmentBasicParameterSet::getTolerenctLossRate() const
{
	return strategyParameters[ Id_TolerenctLossRateArg ]->getDoubleValue(); 
}

double FxInvestmentBasicParameterSet::getLeverage() const
{
	return strategyParameters[ Id_LeverageArg ]->getDoubleValue(); 
}

double FxInvestmentBasicParameterSet::getEntryExchange() const
{
	return strategyParameters[ Id_EntryExchangeArg ]->getDoubleValue(); 
}

double FxInvestmentBasicParameterSet::getTargetSettlementExchangeRateGap() const
{
	return strategyParameters[ Id_TargetSettlementExchangeRateGapArg ]->getDoubleValue(); 
}

double FxInvestmentBasicParameterSet::getLossCutExchangeRateGap() const
{
	return strategyParameters[ Id_LossCutExchangeRateGapArg ]->getDoubleValue(); 
}

double FxInvestmentBasicParameterSet::getSpread() const
{
	return strategyParameters[ Id_SpreadArg ]->getDoubleValue(); 
}

double FxInvestmentBasicParameterSet::getCharge() const
{
	return strategyParameters[ Id_ChargeArg ]->getDoubleValue();
}

int FxInvestmentBasicParameterSet::getTradeCount() const
{
	return static_cast< int >( strategyParameters[ Id_TradeCountArg ]->getDoubleValue() );
}

InvestmentPosition::Type FxInvestmentBasicParameterSet::getInvestmentPositionType() const
{
	return static_cast< InvestmentPosition::Type >( strategyParameters[ Id_InvestmentPositionTypeArg ]->getDoubleValue() );
}


void FxInvestmentBasicParameterSet::setCurrencyCode( NSString* code )
{
	strategyParameters[ Id_CurrencyCode ]->setStringValue( code );
}

void FxInvestmentBasicParameterSet::setTargetCurrencyCode( NSString* code )
{
	strategyParameters[ Id_TargetCurrencyCode ]->setStringValue( code );
}

void FxInvestmentBasicParameterSet::setInvestMoney( double money )
{
	strategyParameters[ Id_InvestMoney ]->setDoubleValue( money );
}

void FxInvestmentBasicParameterSet::setTargetInterest( double interest )
{
	strategyParameters[ Id_TargetInterestArg ]->setDoubleValue( interest );
}

void FxInvestmentBasicParameterSet::setTolerenctLossRate( double rate )
{
	strategyParameters[ Id_TolerenctLossRateArg ]->setDoubleValue( rate );
}

void FxInvestmentBasicParameterSet::setLeverage( double leverage )
{
	strategyParameters[ Id_LeverageArg ]->setDoubleValue( leverage );
}

void FxInvestmentBasicParameterSet::setEntryExchange( double exchange )
{
	strategyParameters[ Id_EntryExchangeArg ]->setDoubleValue( exchange );
}

void FxInvestmentBasicParameterSet::setTargetSettlementExchangeRateGap( double gap )
{
	strategyParameters[ Id_TargetSettlementExchangeRateGapArg ]->setDoubleValue( gap );
}

void FxInvestmentBasicParameterSet::setLossCutExchangeRateGap( double gap )
{
	strategyParameters[ Id_LossCutExchangeRateGapArg ]->setDoubleValue( gap );
}

void FxInvestmentBasicParameterSet::setSpread( double spread )
{
	strategyParameters[ Id_SpreadArg ]->setDoubleValue( spread );
}

void FxInvestmentBasicParameterSet::setCharge( double charge )
{
	strategyParameters[ Id_ChargeArg ]->setDoubleValue( charge );
}

void FxInvestmentBasicParameterSet::setTradeCount( int count )
{
	strategyParameters[ Id_TradeCountArg ]->setDoubleValue( count );
}

void FxInvestmentBasicParameterSet::setInvestmentPositionType( InvestmentPosition::Type type )
{
	strategyParameters[ Id_InvestmentPositionTypeArg ]->setDoubleValue( type );
}


double FxInvestmentBasicParameterSet::getMinimumTargetSettlementExchangeGap() const
{
	double v = 2 * ( getCharge() * ( getEntryExchange() + getSpread() ) / ( getLeverage() * getInvestMoney() ) + getSpread() );
	return v;
}

double FxInvestmentBasicParameterSet::getMaximumLossCutExchangeGap() const
{
	double v = ( getTolerenctLossRate() * getInvestMoney() - 2 * getCharge() ) * ( getEntryExchange() + getSpread() ) / ( getLeverage() * getInvestMoney() ) - 2 * getSpread();
	return v;
}

double FxInvestmentBasicParameterSet::getProfitPerTradeAtTargetExchange() const
{
	double v = getLeverage() * getInvestMoney() * ( getTargetSettlementExchangeRateGap() - 2 * getSpread() ) / ( getEntryExchange() + getSpread() ) - 2 * getCharge();
	return v;
}

double FxInvestmentBasicParameterSet::getLossPerTradeAtLossCutExchange() const
{
	double v = getLeverage() * getInvestMoney() * ( - getLossCutExchangeRateGap() - 2 * getSpread() ) / ( getEntryExchange() + getSpread() ) - 2 * getCharge();
	return v;
}

double FxInvestmentBasicParameterSet::getBreakEvenWinRate() const
{
	double v = ( getLeverage() + 2 * getSpread() ) / ( getTargetSettlementExchangeRateGap() + getMaximumLossCutExchangeGap() ) + 
		2 * getCharge() * ( getEntryExchange() + getSpread() ) / ( getLeverage() * getInvestMoney() * ( getTargetSettlementExchangeRateGap() + getLossCutExchangeRateGap() ) );
	return v;
}

double FxInvestmentBasicParameterSet::getTargetWinRate() const
{
	double v = ( getEntryExchange() + getSpread() ) / ( ( getTargetSettlementExchangeRateGap() + getLossCutExchangeRateGap() ) * getLeverage() * getInvestMoney() ) *
		( getTargetInterest() * getInvestMoney() + getTradeCount() * ( getLeverage() * getInvestMoney() * ( getLossCutExchangeRateGap() + 2 * getSpread() ) / ( getEntryExchange() + getSpread() ) + 2 * getCharge() ) );
	v /= getTradeCount();
	return v;
}
